﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApp
{
    public class Collections
    {
        public void Show()
        {
            _ArrayList(); //动态数组
            _Hashtable(); //哈希表
            _SortedList();//排序列表
            _Stack();     //栈
            _Queue();     //队列
            _BitArray();  //点阵列

        }

        private void _ArrayList()
        {
            var arrayList = new ArrayList();
            arrayList.Add(new Collections());
            arrayList.Add(new { name = "李俊辉" });
            arrayList.Add(new { name = "李俊辉2" });
            arrayList.Add(new { name = "李俊辉3" });

            Array arrayList2 = new object[10];
            arrayList.CopyTo(arrayList2);

            var clone = arrayList.Clone();

            Array arrayList3 = new object[10];
            arrayList.CopyTo(2, arrayList3, 2, 2);

        }
        private void _Hashtable()
        {
            //就是一个key value。key 由对象GetHashCode得来（int32的长度）。大概率重复
            Hashtable hashtable = new Hashtable();
            hashtable.Add(new { id = 1 }, new { name = "bruke" });
            hashtable.Add(new { id = 2 }, new { name = "bruke2" });
            hashtable.Add(new { id = 3 }, new { name = "bruke3" });
            hashtable.Add(new { id = 4 }, new { name = "bruke4" });
            hashtable.Add(1, "1-1");

            hashtable.Remove(new { id = 2 });

            var hash = new { id = 2 }.GetHashCode();
            var hash2 = new { id = 2 }.GetHashCode();

            var obj = hashtable[new { id = 1 }];

        }
        private void _SortedList()
        {
            //是Array+Hashtable的升级版。速度没有hashtable来的更加直接。但是使用的灵活性上大大优势
            var sortedList = new SortedList(new Comparer());
            sortedList.Add(new { id = 1 }, new { name = "bruke" });
            sortedList.Add(new { id = 2 }, new { name = "bruke2" });
            var keyList = sortedList.GetKeyList();      //都是hashtable没有的
            var valueList = sortedList.GetValueList(); //都是hashtable没有的
        }
        public class Comparer : IComparer
        {
            public int Compare(object x, object y)
            {
                return x.GetHashCode() - y.GetHashCode();
            }
        }
        
        private void _Stack()
        {
            //栈：类似弹夹，先进后出。适用于：语法检测，计算逻辑，语法解析
            var stack = new Stack();
            stack.Push(new { id = 1, name = "bruke" });
            stack.Push(new { id = 2, name = "bruke2" });
            stack.Push(new { id = 3, name = "bruke3" });

            var popObj = stack.Pop();//弹出来一个
            stack.Pop();
            stack.Peek();//看一下
            
        }

        /// <summary>
        /// 队列
        /// </summary>
        private void _Queue()
        {
            //队列：先进先出
            var queue = new Queue();
            queue.Enqueue("1");//在队列的末端添加元素
            queue.Enqueue("2");//在队列的末端添加元素
            queue.Enqueue("3");//在队列的末端添加元素
            queue.Dequeue();//删除一个（顶部）
            var peek = queue.Peek();//看一下（顶部）
            queue.TrimToSize();//重新设置队列的容量，因为调用Dequeue方法读取删除元素后不会重新设置队列的容量。
            bool isContains = queue.Contains("1");
        }

        /// <summary>
        /// 点阵列
        /// </summary>
        private void _BitArray()
        {
            //一维bit组
            byte a = 10;
            var bitArray2 = new BitArray(a);
            var bitArray = new BitArray(10);
            //以上2个等同
            bitArray[0] = false;
            bitArray[1] = true;
            Console.Write("bitArray Count:{0},length:{1},值如下:\n", bitArray.Count, bitArray.Length);
            PrintValues(bitArray, 8);//每8个元素为一行打印元素

            //二维bit组
            byte[] myByte1 = new byte[] { 1, 2, 3, 4, 5 }; //创建一个字节数组：[0-4]:值分别为1，2，3，4，5
            var myBit2 = new BitArray(myByte1);//表示：从字节数组创建一个位数组（点阵列）
            //第一个字节值=1，一个字节=8个bit。那么他的值为[00000001]
            //第二个字节值=2，一个字节=8个bit。那么他的值为[00000010]
            //第三个字节值=4，一个字节=8个bit。那么他的值为[00000011].....

            //点阵列：
            //就时他们依次拼接成一个大数组。（注意：每一个字节位置到反转一下，我也不知道微软为什么要这样做）
            //[10000000]拼[01000000]拼[11000000]
            //=40个元素大小的bit数组。
            PrintValues(myBit2, 8);//每8个元素为一行打印元素


        }

        private void PrintValues(IEnumerable myList, int myWidth) //myWidth指定每行显示的个数
        {
            int i = myWidth;
            foreach (Object obj in myList)  //迭代一列数
            {
                if (i <= 0)
                {
                    i = myWidth;
                    Console.WriteLine();
                }
                i--;
                Console.Write("{0,7}", obj);//显示第0个数据obj，占7个符号的位置

            }
            Console.WriteLine();
        }
    }
}
